#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QToolBar>
#include <QTabBar>
#include <QAction>
#include <QStackedWidget>
#include <QFutureWatcher>

#include <dynamicmodel.h>
#include <viewwidget.h>
#include <settingsdialog.h>
#include <homeview.h>

#include "viewinterface.h"
#include "adapterinterface.h"

class TabBar;
class TabWidget;
class TabsStackWidget;
class ViewToolbar;
class ToolBar;
class TestMainWindow;
struct InProcessFileMetaData;

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow();

    QAction * addViewToolButton(const QString & name, QIcon icon);

    TabWidget * currentTabWidget() const;
    QString currentView() const;
    TabBar * tabBar() const;
    ViewToolbar * viewBar() const;

public slots:
    // action handlers
    QString getOpenFileName();
    void openFile();
    void openFile(const QString & fileName);
    void saveFile(const QString & fileName);
#ifdef SERVER_VERSION
    void openServerTab();
#endif // SERVER_VERSION
    void showPluginsWidget();
    void showSettingsDialog();

    // view management
    int addTab(ViewWidget::ViewType type, const QString & tabName);
    void changeView(const QString & viewName);
    void setTab(int index);
    void closeTab(int index);
    void adjustViewBar();
    void adjustToolBar();
    void openDynamicItem(ARSExecItem * item);

    // void loadUseCase(UseCase * uc);
    // void saveUseCase(UseCase * uc);

private slots:
    void openFileFinished();

private:
    /*! \todo replace with some real one */
    QString libFileName(const QString & libName);

    void loadStyleSheets();
    void createMainWigets();
    void createDialogs();
    void createMenus();
    void loadPlugins();
    void loadCorePlugins();
    QObject * loadCorePlugin(const QString & fileName);
    void loadPlugin(const QString & fileName);
    void initViewToolBar();
    void attachModel(int tabIndex, DynamicModel * model);
    void sendEvent(AppEvent * event);
    bool loadSettings();
    void saveSettings();

    ViewToolbar * m_viewToolBar;
    ToolBar * m_toolBar;
    TabBar * m_tabBar;
    TabsStackWidget * m_tabsStack;

    QList<ViewPluginInterface *> m_viewPlugins;
    DynamicModelAdapterPluginInterface * m_iLogAdapterPlugin;
#ifdef SERVER_VERSION
    StaticModelAdapterPluginInterface * m_iServerAdapterPlugin;
#endif // SERVER_VERSION
    QHash<QString, ToolBarItemList> m_viewItems;
    QHash<QString, QString> m_styleSheets;

    SettingsDialog * m_settingsDialog;
    QString m_lastOpenedDir;
    QHash<QFutureWatcher<DynamicModel *> *, QFile *> m_inProcessPool;
};

class TabBar : public QTabBar
{
    Q_OBJECT

public:
    TabBar(QWidget * parent = 0);
};

struct ViewTab
{
    ViewTab();
    ViewTab( const QString & viewName, const QIcon & icon, const QString & pluginName, int index );
    bool isNull() const;

    QString viewName;
    QIcon icon;
    QString pluginName;
    int index;
    bool isVisible;
};

class ViewToolbar : public QTabBar
{
    Q_OBJECT

public:
    ViewToolbar(QWidget * parent = 0);
    int addView(const QString & name, const QIcon & activeIcon, const QIcon & inactiveIcon, const QString & pluginName);
    void setView(const QString & pluginName);
//    QAction * viewAction(const QString & viewName) const;
//    QList<QAction *> viewActions(bool activeOnly = true) const;
    QString view() const;

signals:
    void viewChanged(const QString & viewName);

public slots:
    void tabChanged(int index);
    void setViewVisible(const QString & viewName, bool visible);
    int viewIndex(const QString & pluginName);

private:
    QList<ViewTab *> m_viewTabs;
};

class ToolBar : public QToolBar
{
    Q_OBJECT

public:
    ToolBar(QWidget * parent = 0);

    void addItems(ToolBarItemList itemList, const QString & viewName = QString());
    ToolBarItemList items(const QString & viewName = QString());
    void setItemsVisible(const QString & viewName, bool visible);
    void hideAllViewItems();

private:
    QHash<QString, ToolBarItem *> m_items;
};

class TabWidget : public QStackedWidget
{
    Q_OBJECT

public:
    TabWidget(QWidget * parent = 0);
    void addView(ViewWidget * viewWiget);
    ViewWidget * currentViewWidget() const;
    QString currrentView() const;
    QStringList viewNames() const;
    QList<ViewWidget *> viewWidgets() const;

public slots:
    void setView(const QString & pluginName);
};

class TabsStackWidget : public QStackedWidget
{
    Q_OBJECT

public:
    TabsStackWidget(QWidget * parent);
    TabWidget * tab(int index);
    TabWidget * currentTab();
    void removeTab(int index);
};

#endif // MAINWINDOW_H
